import json
import os.path
import subprocess
import time

from le_engine.config import CommonConfig
from utils.logger import log

class PlayerState:
    start_finished = "start_finished"

class MuMuControl:

    def __init__(self, hide=True):
        self.account = None
        self.root_dir = None
        self.manager = None

        self.hide = hide
        self.init_config()

    def init_config(self):
        from utils.utils import account_config
        account_config = account_config()
        self.account = account_config["account"]
        self.root_dir = account_config["mumu_dir"]
        self.manager = os.path.join(self.root_dir, "shell", "MuMuManager.exe")

        if not os.path.exists(self.manager):
            self.manager = os.path.join(self.root_dir, "nx_main", "MuMuManager.exe")

        self.px_dpi_set()

    def player_state(self, index="0"):
        # 模拟器状态
        result = self.get_device_info(index)
        state = result.get("player_state")
        return state

    def px_dpi_set(self):
        # 设置全局默认值
        self.execute_cmd("setting", "-k", "resolution_dpi.custom", "-val", "280")
        self.execute_cmd("setting", "-k", "resolution_height.custom", "-val", "1080")
        self.execute_cmd("setting", "-k", "resolution_width.custom", "-val", "1920")

    def execute_cmd(self, *args):
        try:
            result = subprocess.run([self.manager, *args], capture_output=True, text=True, encoding='utf-8',
                                    creationflags=subprocess.CREATE_NO_WINDOW)
        except Exception as e:
            log.error(f"执行模拟器命令时报错：{e}")
            return {}
        else:
            try:
                result = json.loads(result.stdout)
                return result
            except Exception as e:
                return {"exception": str(e), "result": result.stdout}

    def android_back(self, index=0):
        try:
            result = self.execute_cmd("adb", "-v", str(index), "-c", "go_back")
            return result
        except Exception as e:
            log.info(f"android_back {e}")
            return {}

    def show_all_device_info(self) -> dict:
        # 获取所有模拟器的信息
        try:
            result = self.execute_cmd("info", "-v", "all")
            if result.get("index"):
                return {result.get("index"): result}
            else:
                return {str(i): result[str(i)] for i in range(len(result))}
        except Exception as e:
            log.info(f"获取模拟器信息失败{e}")
            return {}

    def get_device_info(self, index=None) -> dict:
        if index:
            return self.execute_cmd("info", "-v", index)
        else:
            result = self.execute_cmd("info", "-v", "all")
            if result.get("index"):
                result = {result.get("index"): result}
            return result

    def new_devices(self, name=None):
        result = self.execute_cmd("create")
        if name:
            result = self.execute_cmd("rename", "-v", list(result.keys())[0], "-n", name)
        else:
            result = list(result.values())[0]
        return result

    def delete_device(self, index=None):
        if index:
            result = self.execute_cmd("delete", "-v", str(index))
            return result
        return {}

    def create_devices(self):
        # 根据配置的用户数量创建模拟器
        account_num = len(self.account)

        devices_num = len(self.show_all_device_info())
        if account_num > 0 and devices_num < account_num:
            try:
                result = self.execute_cmd("create", "-n", f"{account_num - devices_num}")
            except Exception as e:
                log.info(f"创建模拟器失败{e}")
                exit()

            return result

        return {}

    def run_device(self, index="0"):
        # 启动某一个模拟器
        try:
            result = self.execute_cmd("control", "-v", f"{str(index)}", "launch")
        except Exception as e:
            log.info(f"启动模拟器 {index} 失败 {e}")
            return {}
        else:
            self.set_device_size_position(index=index)
            if self.hide:
                self.hide_devices(index)
            return result

    def run_all_devices(self):

        # 启动所有模拟器
        devices = ",".join([i for i in self.show_all_device_info()])
        try:
            result = self.execute_cmd("control", "-v", f"{devices}", "launch")
        except Exception as e:
            log.info(f"启动模拟器 {devices} 失败 {e}")
            return {}
        else:
            time.sleep(2)
            self.set_device_size_position()
            time.sleep(1)
            if self.hide:
                self.hide_devices()
        return result

    def set_device_size_position(self, base_px=100, base_py=100, index=None):

        while self.player_state(index) != PlayerState.start_finished:
            time.sleep(1)

        if index is None:
            index = [device for device in self.show_all_device_info()]
        else:
            index = [index]

        base_sw = "830"
        base_sh = "500"

        for i in index:
            px = f"{base_px * (int(i) + 1)}"
            py = f"{base_py * (int(i) + 1)}"
            try:
                log.info(f"{px}, {py}, {base_sw}, {base_sh}")
                result = self.execute_cmd("control", "-v", f"{i}", "layout_window",
                                          "-px", px, "-py", py, "-sw",
                                          base_sw, "-sh", base_sh)
            except Exception as e:
                log.info(f"设置模拟器 {i} 失败 {e}")
                continue
            else:
                log.info(f"设置模拟器 {i} 成功 {result}")

    def shutdown_devices(self, index=None):
        devices = []

        if index:
            result = self.get_device_info(index=index)
            if result.get("adb_host_ip"):
                devices = index
        else:
            for i, device in self.show_all_device_info().items():
                if device.get("adb_host_ip"):
                    devices.append(i)
        if devices:
            try:
                result = self.execute_cmd("control", "-v", ",".join(devices), "shutdown")
                return result
            except Exception as e:
                log.info(f"关闭模拟器失败 {e}")
        return {}

    def restart_devices(self, index=None):
        self.shutdown_devices(index=index)
        if index is None:
            self.run_all_devices()
        else:
            self.run_device(index=index)

    def show_devices(self, index=None):
        devices = ",".join([i for i in self.show_all_device_info()]) if not index else index
        try:
            result = self.execute_cmd("control", "-v", devices, "show_window")
            return result
        except Exception as e:
            log.info(f"显示模拟器失败 {e}")
            return {}

    def hide_devices(self, index=None):
        devices = ",".join([i for i in self.show_all_device_info()]) if not index else index
        try:
            result = self.execute_cmd("control", "-v", devices, "hide_window")
            return result
        except Exception as e:
            log.info(f"显示模拟器失败 {e}")
            return {}

    def get_app_info(self, index=None, pkg_name=None):
        if index is None:
            index = ",".join([i for i in self.show_all_device_info()])

        if pkg_name is None:
            pkg_name = CommonConfig.package_name

        result = self.execute_cmd("control", "-v", index, "app", "info", "-pkg", pkg_name)
        return result

    def install_app(self, index=None, pkg_path=None):
        if index and pkg_path:
            return self.execute_cmd("control", "-v", index, "app", "install", "-apk", pkg_path)

    def init_devices(self):
        self.create_devices()
        self.run_all_devices()
        devices = self.show_all_device_info()
        return devices


if __name__ == '__main__':
    mm = MuMuControl()
    # mm.init_devices()
    # mm.show_devices()
    # mm.hide_devices()
    # mm.shutdown_devices()
    print(mm)